﻿using System;
using Dataweb.NShape;
using Dataweb.NShape.Advanced;
using System.Drawing;
using System.ComponentModel;
using System.Collections.Generic;
using cz.zcu.PreSti.Components;

namespace cz.zcu.PreSti.Shapes
{
    class InputMouseSymbol : CircleBase, ISymbol
    { 
        protected internal InputMouseSymbol(ShapeType shapeType, Template template)
            : base(shapeType, template)
        {
        }


        protected internal InputMouseSymbol(ShapeType shapeType, IStyleSet styleSet)
            : base(shapeType, styleSet)
        {
        }

        public override Shape Clone()
        {
            Shape result = new InputMouseSymbol(Type, (Template)null);
            result.CopyFrom(this);
            return result;
        }

        protected override void InitializeToDefault(IStyleSet styleSet)
        {
            base.InitializeToDefault(styleSet);
            Text = "M";
        }

        protected override Rectangle CalculateBoundingRectangle(bool tight)
        {
            return base.CalculateBoundingRectangle(true);
        }

        protected override bool CalculatePath()
        {
            if (base.CalculatePath())
            {
                Path.Reset();
                int left = (int)Math.Round(-Diameter / 2f);
                int top = left;
                int right = left + Diameter;
                int bottom = right;
                Path.StartFigure();
                //Path.AddEllipse(left, top - 5 / 4f, Diameter, Diameter);
                Path.AddPie(new Rectangle(left, top, Diameter, Diameter), 360 - 45, 270);
                Path.AddPolygon(new PointF[] { new PointF(left, top + Diameter / 2f - connectorWidth), new PointF(left + connectorWidth, top + Diameter / 2f), new PointF(left, top + Diameter / 2f + connectorWidth) });
                Path.AddPolygon(new PointF[] { new PointF(left, top + Diameter / 2f + connectorWidth), new PointF(left + connectorWidth + 2, top + Diameter / 2f + 2 * connectorWidth - 3), new PointF(left + 4, top + Diameter / 2f + 3 * connectorWidth - 1) });
                Path.AddPolygon(new PointF[] { new PointF(right, top + Diameter / 2f - connectorWidth), new PointF(right - connectorWidth, top + Diameter / 2f), new PointF(right, top + Diameter / 2f + connectorWidth) });
                Path.AddCurve(new PointF[] { new PointF(-8, bottom), new PointF(-4, bottom - 4), new PointF(0, bottom) }, 1);
                Path.AddCurve(new PointF[] { new PointF(0, bottom), new PointF(4, bottom - 4), new PointF(8, bottom) }, 1);
                Path.CloseFigure();
                return true;
            }
            else return false;
        }

        public override bool HasControlPointCapability(ControlPointId controlPointId, ControlPointCapabilities controlPointCapability)
        {
            switch (controlPointId)
            {
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    return ((controlPointCapability & ControlPointCapabilities.Connect) != 0);
                default:
                    return base.HasControlPointCapability(controlPointId, controlPointCapability);
            }
        }


        protected override int ControlPointCount { get { return 5; } }

        protected override void CalcControlPoints()
        {
            int left = (int)Math.Round(-Diameter / 2f);
            int right = left + Diameter;

            ControlPoints[0].X = left;
            controlPoints[0].Y = 0;
            ControlPoints[1].X = left + 2;
            controlPoints[1].Y = 2 * connectorWidth;
            ControlPoints[2].X = right;
            ControlPoints[2].Y = 0;
            ControlPoints[3].X = -4;
            ControlPoints[3].Y = right;
            ControlPoints[4].X = 4;
            ControlPoints[4].Y = right;
        }

        private int connectorWidth = 5;


        #region ISymbol Members

        public BaseComponent initializeComponent(IPresentation p)
        {
            InputMouseModel model = (InputMouseModel)this.ModelObject;
            InputMouseComponent input = new InputMouseComponent(p);
            input.LeftButtonEnabled = model.LeftButtonEnabled;
            input.RightButtonEnabled = model.RightButtonEnabled;
            return input;
        }

        public int ActionsCount
        {
            get { return 2; }
        }

        public int EventsCount
        {
            get { return 1; }
        }

        public int SettersCount
        {
            get { return 0; }
        }

        public int GettersCount
        {
            get { return 2; }
        }

        public string GetTitleForAction(int id)
        {
            switch (id)
            {
                case 0:
                    return "Enable";
                case 1:
                    return "Disable";
            }
            return "";
        }

        public string GetTitleForEvent(int id)
        {
            return "Button pressed";
        }

        public string GetTitleForSetter(int id)
        {
            return "";
        }

        public string GetTitleForGetter(int id)
        {
            switch (id)
            {
                case 0:
                    return "X position";
                case 1:
                    return "Y position";
            }
            return "";
        }

        #endregion

        internal static Shape CreateInstance(ShapeType shapeType, Template template)
        {
            return new InputMouseSymbol(shapeType, template);
        }
    }

    public class InputMouseModel : ModelObjectBase
    {

        #region Fields

        private bool leftButtonEnabled;
        private bool rightButtonEnabled;
        private char securityDomainName = 'A';

        private const int PropertyIdLeftButtonEnabled = 1;
        private const int PropertyIdRightButtonEnabled = 1;

        #endregion

        #region properties

        [Category("Presentation")]
        [Description("Indicates wheather the event is raised when left button is pressed")]
        [PropertyMappingId(PropertyIdLeftButtonEnabled)]
        public bool LeftButtonEnabled
        {
            get
            {
                return leftButtonEnabled;
            }
            set
            {
                leftButtonEnabled = value;
            }
        }

        [Category("Presentation")]
        [Description("Indicates wheather the event is raised when left button is pressed")]
        [PropertyMappingId(PropertyIdRightButtonEnabled)]
        public bool RightButtonEnabled
        {
            get
            {
                return rightButtonEnabled;
            }
            set
            {
                rightButtonEnabled = value;
            }
        }

        #endregion

        public static InputMouseModel CreateInstance(ModelObjectType modelObjectType)
        {
            return new InputMouseModel(modelObjectType);
        }


        protected internal InputMouseModel(ModelObjectType modelObjectType)
            : base(modelObjectType)
        {
            this.terminalCount = 5;
        }


        protected internal InputMouseModel(InputMouseModel source)
            : base(source)
        {
            LeftButtonEnabled = source.LeftButtonEnabled;
            RightButtonEnabled = source.RightButtonEnabled;
            this.terminalCount = 5;
        }


        public override IModelObject Clone()
        {
            return new InputMouseModel(this);
        }


        public override IEnumerable<MenuItemDef> GetMenuItemDefs()
        {
            throw new NotImplementedException();
        }


        public override void Connect(TerminalId ownTerminalId, IModelObject targetConnector, TerminalId targetTerminalId)
        {
        }


        public override void Disconnect(TerminalId ownTerminalId, IModelObject targetConnector, TerminalId targetTerminalId)
        {
        }

        public override char SecurityDomainName
        {
            get { return securityDomainName; }
            set
            {
                if (value < 'A' || value > 'Z')
                    throw new ArgumentOutOfRangeException("SecurityDomainName", "The domain qualifier has to be an upper case  ANSI letter (A-Z).");
                securityDomainName = value;
            }
        }


        #region IEntity Members

        public static new IEnumerable<EntityPropertyDefinition> GetPropertyDefinitions(int version)
        {
            foreach (EntityPropertyDefinition pi in ModelObjectBase.GetPropertyDefinitions(version))
                yield return pi;
            yield return new EntityFieldDefinition("LeftButtonEnabled", typeof(bool));
            yield return new EntityFieldDefinition("RightButtonEnabled", typeof(bool));
        }

        protected override void LoadFieldsCore(IRepositoryReader reader, int version)
        {
            base.LoadFieldsCore(reader, version);
            LeftButtonEnabled = reader.ReadBool();
            RightButtonEnabled = reader.ReadBool();
        }

        protected override void SaveFieldsCore(IRepositoryWriter writer, int version)
        {
            base.SaveFieldsCore(writer, version);
            writer.WriteBool(LeftButtonEnabled);
            writer.WriteBool(RightButtonEnabled);
        }

        #endregion
    }
}
